package com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.common.aliyunImg.AliyunImgUtil;
import com.xyht.sca_s.student_manage_system.common.aliyunImg.entity.resp.CompareFaceResp;
import com.xyht.sca_s.student_manage_system.common.aliyunImg.entity.resp.RecognizeFaceResp;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ExceptionCast;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.OrgUserStuUtil;
import com.xyht.sca_s.student_manage_system.modules.appDynamic.entity.resp.UserInfoResp;
import com.xyht.sca_s.student_manage_system.modules.common.constant.TaskNameExample;
import com.xyht.sca_s.student_manage_system.modules.common.constant.TaskTypeConstant;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTask;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTaskDetail;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskMapper;
import com.xyht.sca_s.student_manage_system.modules.dormitory.entity.SmsDormitory;
import com.xyht.sca_s.student_manage_system.modules.dormitory.entity.SmsDormitoryBed;
import com.xyht.sca_s.student_manage_system.modules.dormitory.mapper.SmsDormitoryBedMapper;
import com.xyht.sca_s.student_manage_system.modules.dormitory.mapper.SmsDormitoryMapper;
import com.xyht.sca_s.student_manage_system.modules.enrollmentManagement.entity.resp.OrgStructureResp;
import com.xyht.sca_s.student_manage_system.modules.org.constants.UpdateTypeConstant;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgStructure;
import com.xyht.sca_s.student_manage_system.modules.org.entity.SmsOrgUserRelation;
import com.xyht.sca_s.student_manage_system.modules.org.entity.resp.SmsOrgStructureResp;
import com.xyht.sca_s.student_manage_system.modules.org.mapper.SmsOrgStructureMapper;
import com.xyht.sca_s.student_manage_system.modules.org.mapper.SmsOrgUserRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.org.service.SmsOrgUserRelationService;
import com.xyht.sca_s.student_manage_system.modules.student.entity.SmsStudentInfo;
import com.xyht.sca_s.student_manage_system.modules.student.entity.SmsUserStudentRelation;
import com.xyht.sca_s.student_manage_system.modules.student.entity.resp.SmsStudentInfoResp;
import com.xyht.sca_s.student_manage_system.modules.student.mapper.SmsStudentInfoMapper;
import com.xyht.sca_s.student_manage_system.modules.student.mapper.SmsUserStudentRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.student.service.SmsUserStudentRelationService;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUserRoleRelation;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsRoleMapper;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserMapper;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsUserRoleRelationMapper;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.constant.ChargePlanConstant;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.constant.RegistrationProcessDetailConstant;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.*;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.req.*;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.entity.resp.*;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.mapper.SmsWnsChargePlanMapper;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.mapper.SmsWnsRegistrationProcessDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.mapper.SmsWnsRegistrationProcessMapper;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.mapper.SmsWnsStudentCardInformationMapper;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.service.SmsStuOrgUpdateHistoryService;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.service.SmsWnsRegistrationProcessDetailService;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.util.AssistantUtil;
import com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.util.CategoryItemUtil;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.*;
import static com.xyht.sca_s.student_manage_system.modules.chargePayment.constant.StudentInfoApproveTypeConstant.*;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskDetailReason.*;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskStatus.*;
import static com.xyht.sca_s.student_manage_system.modules.org.constants.UpdateTypeConstant.UPDATE_TYPE_LIST;
import static com.xyht.sca_s.student_manage_system.modules.student.constant.StudentHealthStatus.STUDENT_NOT_HEALTH;
import static com.xyht.sca_s.student_manage_system.modules.user.constant.DefaultRole.ROLE_STUDENT;
import static com.xyht.sca_s.student_manage_system.modules.user.constant.TeacherAndStudentFlag.STUDENT_FLAG;
import static com.xyht.sca_s.student_manage_system.modules.user.constant.commonConstant.DEFAULT_PASSWORD;
import static com.xyht.sca_s.student_manage_system.modules.welcomeNewStudent.constant.RegistrationProcessDetailConstant.*;

/**
 * <p>
 * 报到流程步骤表 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2024-01-08
 */
@Service
public class SmsWnsRegistrationProcessDetailServiceImpl extends ServiceImpl<SmsWnsRegistrationProcessDetailMapper, SmsWnsRegistrationProcessDetail> implements SmsWnsRegistrationProcessDetailService {
    @Resource
    private SmsImportTaskMapper smsImportTaskMapper;
    @Resource
    private PlatformTransactionManager transactionManager;
    @Resource
    private SmsOrgStructureMapper smsOrgStructureMapper;
    @Resource
    private SmsStudentInfoMapper smsStudentInfoMapper;
    @Resource
    private SmsUserStudentRelationMapper smsUserStudentRelationMapper;
    @Resource
    private SmsImportTaskDetailMapper smsImportTaskDetailMapper;
    @Resource
    private SmsUserMapper smsUserMapper;
    @Resource
    private SmsOrgUserRelationMapper smsOrgUserRelationMapper;
    @Resource
    private SmsOrgUserRelationService smsOrgUserRelationService;
    @Resource
    private SmsUserRoleRelationMapper smsUserRoleRelationMapper;
    @Resource
    private SmsWnsRegistrationProcessMapper smsWnsRegistrationProcessMapper;
    @Resource
    private SmsRoleMapper smsRoleMapper;
    @Resource
    private AssistantUtil assistantUtil;
    @Resource
    private SmsUserStudentRelationService smsUserStudentRelationService;
    @Resource
    private SmsWnsChargePlanMapper smsWnsChargePlanMapper;
    @Resource
    private SmsWnsStudentCardInformationMapper smsWnsStudentCardInformationMapper;
    @Resource
    private CategoryItemUtil categoryItemUtil;
    @Resource
    private SmsWnsRegistrationProcessDetailMapper smsWnsRegistrationProcessDetailMapper;
    @Resource
    private SmsDormitoryBedMapper smsDormitoryBedMapper;
    @Resource
    private SmsDormitoryMapper smsDormitoryMapper;
    @Resource
    private OrgUserStuUtil orgUserStuUtil;
    @Resource
    private SmsStuOrgUpdateHistoryService smsStuOrgUpdateHistoryService;

    @Override
    @Transactional
    public ResponseResult stuEnrollmentStatus(String userId) {
        // 查询所有步骤信息
        List<SmsWnsRegistrationProcess> processList = smsWnsRegistrationProcessMapper.selectList(new LambdaQueryWrapper<SmsWnsRegistrationProcess>()
                .eq(SmsWnsRegistrationProcess::getIsUse, true) // 已启用
                .orderByAsc(SmsWnsRegistrationProcess::getSort)); // 按顺序排序
        List<String> processIdList = processList.stream().map(SmsWnsRegistrationProcess::getId).collect(Collectors.toList());

        // 删除未启用的流程
        this.remove(new LambdaQueryWrapper<SmsWnsRegistrationProcessDetail>()
                .notIn(SmsWnsRegistrationProcessDetail::getProcessId, processIdList.isEmpty() ? Collections.singletonList("") : processIdList)
                .eq(SmsWnsRegistrationProcessDetail::getUserId, userId));

        // 查询学生入学办理事项完成情况
        List<SmsWnsRegistrationProcessDetail> processDetailList = this.list(new LambdaQueryWrapper<SmsWnsRegistrationProcessDetail>()
                .in(SmsWnsRegistrationProcessDetail::getProcessId, processIdList)
                .eq(SmsWnsRegistrationProcessDetail::getUserId, userId));
        List<SmsWnsRegistrationProcessDetail> insertDetailList = new ArrayList<>();
        for (SmsWnsRegistrationProcess process : processList) {
            List<SmsWnsRegistrationProcessDetail> detailList = processDetailList.stream().filter(processDetail -> processDetail.getProcessId().equals(process.getId())).collect(Collectors.toList());
            if (detailList.isEmpty()) {
                SmsWnsRegistrationProcessDetail detail = new SmsWnsRegistrationProcessDetail();
                detail.setUserId(userId);
                detail.setProcessId(process.getId());
                detail.setSort(process.getSort());
                detail.setStatus(RegistrationProcessDetailConstant.REGISTRATION_PROCESS_DETAIL_STATUS_NOT_START); // 未开始
                insertDetailList.add(detail);
            } else {
                // 校验顺序是否正确
                SmsWnsRegistrationProcessDetail detail = detailList.get(0);
                if (!Objects.equals(process.getSort(), detail.getSort())) {
                    detail.setSort(process.getSort());
                    this.updateById(detail);
                }
            }
        }

        // 保存入学办理事项
        if (!insertDetailList.isEmpty()) {
            this.saveBatch(insertDetailList);
        }
        processDetailList.addAll(insertDetailList);

        List<SmsWnsRegistrationProcessDetailResp> processDetailRespList = processDetailList.stream().sorted(new Comparator<SmsWnsRegistrationProcessDetail>() {
            @Override
            public int compare(SmsWnsRegistrationProcessDetail o1, SmsWnsRegistrationProcessDetail o2) {
                return o1.getSort().compareTo(o2.getSort());
            }
        }).map(detail -> {
            SmsWnsRegistrationProcessDetailResp detailResp = new SmsWnsRegistrationProcessDetailResp();
            BeanUtils.copyProperties(detail, detailResp);

            // 设置步骤信息
            List<SmsWnsRegistrationProcess> filterProcessListList = processList.stream().filter(process -> process.getId().equals(detail.getProcessId())).collect(Collectors.toList());
            if (!filterProcessListList.isEmpty()) {
                detailResp.setProcess(filterProcessListList.get(0));
            }

            return detailResp;
        }).collect(Collectors.toList());

        return CommonResult.success(processDetailRespList);
    }

    @Override
    public ResponseResult listStuNumByGrade(Integer pageNum, Integer pageSize, String collegeId, String majorId, String grade) {
        LambdaQueryWrapper<SmsOrgStructure> queryWrapper = new LambdaQueryWrapper<SmsOrgStructure>()
                .like(SmsOrgStructure::getOrgName, grade)
                .eq(SmsOrgStructure::getLevel, 5)
                .orderByDesc(SmsOrgStructure::getCreateTime);

        // collegeId(学院)不为空
        if (!isNullOrEmpty(collegeId)) {
            // 获取所有专业id
            List<SmsOrgStructure> orgStructureList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                    .eq(SmsOrgStructure::getParentId, collegeId));
            List<Integer> majorIdList = orgStructureList.stream().map(SmsOrgStructure::getId).collect(Collectors.toList());
            queryWrapper.in(SmsOrgStructure::getParentId, majorIdList.isEmpty() ? new ArrayList<>() : majorIdList);
        }

        // majorId(专业)不为空
        if (!isNullOrEmpty(majorId)) {
            queryWrapper.eq(SmsOrgStructure::getParentId, majorId);
        }

        Page<SmsOrgStructure> page = new Page<>(pageNum, pageSize);
        smsOrgStructureMapper.selectPage(page, queryWrapper);
        List<ListStuByGradeResp> collect = page.getRecords().stream().map(gradeOrg -> {
            // 获取专业人数及男女生人数
            ListStuByGradeResp resp = getStuCount(gradeOrg);

            // 设置年级名
            resp.setGradeName(gradeOrg.getOrgName());
            resp.setGradeId(String.valueOf(gradeOrg.getId()));

            // 设置专业名
            SmsOrgStructure majorOrg = smsOrgStructureMapper.selectById(gradeOrg.getParentId());
            if (majorOrg != null) {
                resp.setMajorName(majorOrg.getOrgName()); // 专业名
                resp.setMajorId(String.valueOf(majorOrg.getId())); // 专业名

                // 设置学院名
                SmsOrgStructure collegeOrg = smsOrgStructureMapper.selectById(majorOrg.getParentId());
                if (collegeOrg != null) {
                    resp.setCollegeName(collegeOrg.getOrgName()); // 学院名
                }
            }

            return resp;
        }).collect(Collectors.toList());

        return CommonResult.success(collect, (int) page.getTotal());
    }

    /**
     * 获取某专业人数
     *
     * @param gradeOrg 专业某年级
     * @return 专业人数及男女生人数
     */
    private ListStuByGradeResp getStuCount(SmsOrgStructure gradeOrg) {
        int stuCount = 0;
        int boyCount = 0;
        int girlCount = 0;

        // 获取所有班级
        List<SmsOrgStructure> classOrgList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                .eq(SmsOrgStructure::getParentId, gradeOrg.getId()));
        if (!classOrgList.isEmpty()) {
            for (SmsOrgStructure classOrg : classOrgList) {
                // 获取当前班级学生 userIdList
                List<SmsOrgUserRelation> userRelationList = smsOrgUserRelationMapper.selectList(new LambdaQueryWrapper<SmsOrgUserRelation>()
                        .eq(SmsOrgUserRelation::getOrgId, classOrg.getId()));

                // 根据 userIdList 获取所有学生信息
                if (!userRelationList.isEmpty()) {
                    List<String> userIdList = userRelationList.stream().map(SmsOrgUserRelation::getUserId).distinct().collect(Collectors.toList());
                    List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                            .in(SmsUserStudentRelation::getUserId, userIdList));
                    if (!userStudentRelationList.isEmpty()) {
                        List<String> stuIdList = userStudentRelationList.stream().map(SmsUserStudentRelation::getStuId).distinct().collect(Collectors.toList());
                        List<SmsStudentInfo> studentInfoList = smsStudentInfoMapper.selectBatchIds(stuIdList);

                        // 过滤男生信息
                        List<SmsStudentInfo> boyInfoList = studentInfoList.stream().filter(studentInfo -> Objects.equals(studentInfo.getStuSex(), "男")).collect(Collectors.toList());

                        stuCount += studentInfoList.size(); // 学生数量累加
                        boyCount += boyInfoList.size(); // 男生数量累加
                        girlCount += studentInfoList.size() - boyInfoList.size(); // 女生数量累加
                    }
                }
            }

            ListStuByGradeResp resp = new ListStuByGradeResp();
            resp.setStuCount(stuCount);
            resp.setBoyCount(boyCount);
            resp.setGirlCount(girlCount);
            return resp;
        }

        ListStuByGradeResp resp = new ListStuByGradeResp();
        resp.setStuCount(0);
        resp.setBoyCount(0);
        resp.setGirlCount(0);
        return resp;
    }

    @Override
    @Async
    public Future<ResponseResult> batchAddStuInfo(SmsWnsNewStuBatchAddReq newStuBatchAddReq, String userId) {
        if (isNullOrEmpty(newStuBatchAddReq.getStuGrade(), newStuBatchAddReq.getType()) || (newStuBatchAddReq.getType() != 1 && newStuBatchAddReq.getType() != 2)) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        List<SmsStudentInfo> studentInfoList = newStuBatchAddReq.getStudentInfoList();
        if (studentInfoList == null || studentInfoList.isEmpty()) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }

        // 创建导入任务
        SmsImportTask smsImportTask = new SmsImportTask();
        smsImportTask.setTaskName(TaskNameExample.TASK_NAME_NEW_STUDENT_INFO_IMPORT);
        smsImportTask.setUserId(userId);
        smsImportTask.setStatus(TASK_STATUS_DOING); // 任务状态 0:进行中
        smsImportTask.setTaskType(TaskTypeConstant.TASK_TYPE_NEW_STUDENT_INFO);
        smsImportTaskMapper.insert(smsImportTask);
        String taskId = smsImportTask.getId();
        if (isNullOrEmpty(taskId)) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }

        // 批量导入新生信息
        int OFFSET_ROW = 1; // 初始化行数
        int taskStatus = TASK_STATUS_DONE; // 任务状态: 完成
        // 获取所有院系
        List<SmsOrgStructure> collegeList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                .eq(SmsOrgStructure::getParentId, 3)
                .eq(SmsOrgStructure::getLevel, 3));

        for (int i = 0; i < studentInfoList.size(); i++) {
            // 开启事务
            DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
            // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
            dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 设置嵌套事务
            TransactionStatus status = transactionManager.getTransaction(dt);
            try {
                SmsStudentInfo studentInfo = studentInfoList.get(i);
                // 必填字段验证(学号、姓名、手机号、身份证号、院系、专业)
                if (isNullOrEmpty(studentInfo.getStuNo(), studentInfo.getStuName(), studentInfo.getStuTel(),
                        studentInfo.getStuIdCard(), studentInfo.getStuCollege(), studentInfo.getStuMajor())) {
                    transactionManager.rollback(status);
                    createImportTaskDetail(studentInfo.getStuNo(), studentInfo.getStuName(), taskId, REASON_INVALID_PARAM, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }

                // 校验手机号格式是否有误
                if (!isValidPhone(studentInfo.getStuTel())) {
                    transactionManager.rollback(status);
                    createImportTaskDetail(studentInfo.getStuNo(), studentInfo.getStuName(), taskId, REASON_NEW_STUDENT_PHONE_FORMAT_ERROR, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }

                // 校验身份证号格式是否有误
                if (!isValidIDCard(studentInfo.getStuIdCard())) {
                    transactionManager.rollback(status);
                    createImportTaskDetail(studentInfo.getStuNo(), studentInfo.getStuName(), taskId, REASON_NEW_STUDENT_ID_CARD_FORMAT_ERROR, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }

                // 校验院系是否存在
                List<SmsOrgStructure> stuCollegeList = collegeList.stream().filter(stuCollege -> stuCollege.getOrgName().equals(studentInfo.getStuCollege())).collect(Collectors.toList());
                if (stuCollegeList.isEmpty()) {
                    transactionManager.rollback(status);
                    createImportTaskDetail(studentInfo.getStuNo(), studentInfo.getStuName(), taskId, REASON_ORG_COLLEGE_NOT_EXIST, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }
                SmsOrgStructure stuCollege = stuCollegeList.get(0); // 院系

                // 校验专业是否存在
                List<SmsOrgStructure> stuMajorList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                        .eq(SmsOrgStructure::getParentId, stuCollege.getId())
                        .eq(SmsOrgStructure::getOrgName, studentInfo.getStuMajor()));
                if (stuMajorList.isEmpty()) {
                    transactionManager.rollback(status);
                    createImportTaskDetail(studentInfo.getStuNo(), studentInfo.getStuName(), taskId, REASON_ORG_MAJOR_NOT_EXIST, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }
                SmsOrgStructure stuMajor = stuMajorList.get(0); // 专业

                // 构造班级名称: 年级 + 专业 + 1班 (例: 2024级艺术设计1班)
                String stuClassName = newStuBatchAddReq.getStuGrade() + stuMajor.getOrgName() + "1班";

                // 校验年级是否存在
                List<SmsOrgStructure> stuGradeList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                        .eq(SmsOrgStructure::getParentId, stuMajor.getId())
                        .eq(SmsOrgStructure::getOrgName, newStuBatchAddReq.getStuGrade()));
                List<Integer> orgIdList = new ArrayList<>(); // 记录学生所属班级id
                if (!stuGradeList.isEmpty()) { // 存在年级
                    SmsOrgStructure stuGrade = stuGradeList.get(0); // 年级
                    // 校验班级是否存在
                    List<SmsOrgStructure> stuClassList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                            .eq(SmsOrgStructure::getParentId, stuGrade.getId())
                            .eq(SmsOrgStructure::getOrgName, stuClassName));
                    if (stuClassList.isEmpty()) { // 班级不存在
                        // 创建班级
                        SmsOrgStructure stuClass = new SmsOrgStructure();
                        stuClass.setParentId(stuGrade.getId()); // 年级id
                        stuClass.setOrgName(stuClassName); // 班级名称
                        stuClass.setLevel(String.valueOf(Integer.parseInt(stuGrade.getLevel()) + 1)); // 层级 = 年级层级 + 1
                        stuClass.setCanDeleted(0); // 不能删除
                        smsOrgStructureMapper.insert(stuClass);
                        orgIdList.add(stuClass.getId());
                    } else {
                        orgIdList.add(stuClassList.get(0).getId());
                    }
                } else { // 不存在年级
                    // 创建年级
                    SmsOrgStructure stuGrade = new SmsOrgStructure();
                    stuGrade.setParentId(stuMajor.getId()); // 专业层级id
                    stuGrade.setOrgName(newStuBatchAddReq.getStuGrade()); // 年级名称
                    stuGrade.setLevel(String.valueOf(Integer.parseInt(stuMajor.getLevel()) + 1)); // 层级 = 专业层级 + 1
                    stuGrade.setCanDeleted(0); // 不能删除
                    smsOrgStructureMapper.insert(stuGrade);

                    // 创建班级
                    SmsOrgStructure stuClass = new SmsOrgStructure();
                    stuClass.setParentId(stuGrade.getId()); // 年级id
                    stuClass.setOrgName(stuClassName); // 班级名称
                    stuClass.setLevel(String.valueOf(Integer.parseInt(stuGrade.getLevel()) + 1)); // 层级 = 年级层级 + 1
                    stuClass.setCanDeleted(0); // 不能删除
                    smsOrgStructureMapper.insert(stuClass);
                    orgIdList.add(stuClass.getId());
                }

                // 去除名字空格
                String newName = StringUtils.deleteWhitespace(studentInfo.getStuName());
                studentInfo.setStuName(newName);
                // 根据添加类型添人
                switch (newStuBatchAddReq.getType()) {
                    case UpdateTypeConstant.UPDATE_TYPE_UPDATE_ADD: // 更新添加
                        // 根据学号查询当前学生是否存在
                        SmsStudentInfo student = smsStudentInfoMapper.selectOne(new LambdaQueryWrapper<SmsStudentInfo>()
                                .eq(SmsStudentInfo::getStuNo, studentInfo.getStuNo()));
                        if (student != null) { // 存在学生信息
                            // 获取学生对应账号
                            List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                                    .eq(SmsUserStudentRelation::getStuId, student.getId()));
                            SmsUser user = smsUserMapper.selectById(userStudentRelationList.get(0).getUserId());

                            // 校验身份证号是否重复
                            Integer idCardCount = smsStudentInfoMapper.selectCount(new LambdaQueryWrapper<SmsStudentInfo>()
                                    .eq(SmsStudentInfo::getStuIdCard, studentInfo.getStuIdCard())
                                    .ne(SmsStudentInfo::getId, student.getId()));
                            if (idCardCount > 1) {
                                transactionManager.rollback(status);
                                createImportTaskDetail(studentInfo.getStuNo(), studentInfo.getStuName(), taskId, REASON_NEW_STUDENT_ID_CARD_EXIST, String.valueOf(i + OFFSET_ROW));
                                taskStatus = TASK_STATUS_ERR;
                                continue;
                            }

                            // 校验手机号是否重复
                            Integer telCount = smsUserMapper.selectCount(new LambdaQueryWrapper<SmsUser>()
                                    .eq(SmsUser::getTel, studentInfo.getStuTel())
                                    .ne(SmsUser::getId, user.getId()));
                            if (telCount > 1) {
                                transactionManager.rollback(status);
                                createImportTaskDetail(studentInfo.getStuNo(), studentInfo.getStuName(), taskId, REASON_TEL_EXIST, String.valueOf(i + OFFSET_ROW));
                                taskStatus = TASK_STATUS_ERR;
                                continue;
                            }

                            // 更新学生信息
                            studentInfo.setId(student.getId());
                            smsStudentInfoMapper.updateById(studentInfo);

                            // 更新学生账号信息
                            user.setRealName(studentInfo.getStuName());
                            user.setTel(studentInfo.getStuTel());
                            smsUserMapper.updateById(user);

                            addStudentUserRelation(user.getId(), studentInfo.getId(), orgIdList);
                        } else { // 不存在学生信息
                            // 校验身份证号是否重复
                            Integer idCardCount = smsStudentInfoMapper.selectCount(new LambdaQueryWrapper<SmsStudentInfo>()
                                    .eq(SmsStudentInfo::getStuIdCard, studentInfo.getStuIdCard()));
                            if (idCardCount > 1) {
                                transactionManager.rollback(status);
                                createImportTaskDetail(studentInfo.getStuNo(), studentInfo.getStuName(), taskId, REASON_NEW_STUDENT_ID_CARD_EXIST, String.valueOf(i + OFFSET_ROW));
                                taskStatus = TASK_STATUS_ERR;
                                continue;
                            }

                            // 校验手机号是否重复
                            Integer telCount = smsUserMapper.selectCount(new LambdaQueryWrapper<SmsUser>()
                                    .eq(SmsUser::getTel, studentInfo.getStuTel()));
                            if (telCount > 1) {
                                transactionManager.rollback(status);
                                createImportTaskDetail(studentInfo.getStuNo(), studentInfo.getStuName(), taskId, REASON_TEL_EXIST, String.valueOf(i + OFFSET_ROW));
                                taskStatus = TASK_STATUS_ERR;
                                continue;
                            }

                            // 新增学生信息
                            smsStudentInfoMapper.insert(studentInfo);

                            // 删除学号冲突的账号
                            smsUserMapper.delete(new LambdaQueryWrapper<SmsUser>()
                                    .eq(SmsUser::getUsername, studentInfo.getStuNo()));
                            // 新增学生账号
                            SmsUser user = new SmsUser();
                            user.setUsername(studentInfo.getStuNo());
                            user.setRealName(studentInfo.getStuName());
                            user.setPassword(DEFAULT_PASSWORD);
                            user.setIsUse(0); // 账号未激活
                            user.setFlag(STUDENT_FLAG);
                            user.setTel(studentInfo.getStuTel());
                            smsUserMapper.insert(user);

                            addStudentUserRelation(user.getId(), studentInfo.getId(), orgIdList);
                        }

                        break;
                    case UpdateTypeConstant.UPDATE_TYPE_COVER_ADD: // 覆盖添加
                        // 删除原有学生信息
                        smsStudentInfoMapper.delete(new LambdaQueryWrapper<SmsStudentInfo>()
                                .eq(SmsStudentInfo::getStuNo, studentInfo.getStuNo()));

                        // 删除原有学生账号
                        smsUserMapper.delete(new LambdaQueryWrapper<SmsUser>()
                                .eq(SmsUser::getUsername, studentInfo.getStuNo()));

                        // 校验身份证号是否重复
                        Integer idCardCount = smsStudentInfoMapper.selectCount(new LambdaQueryWrapper<SmsStudentInfo>()
                                .eq(SmsStudentInfo::getStuIdCard, studentInfo.getStuIdCard()));
                        if (idCardCount > 1) {
                            transactionManager.rollback(status);
                            createImportTaskDetail(studentInfo.getStuNo(), studentInfo.getStuName(), taskId, REASON_NEW_STUDENT_ID_CARD_EXIST, String.valueOf(i + OFFSET_ROW));
                            taskStatus = TASK_STATUS_ERR;
                            continue;
                        }

                        // 校验手机号是否重复
                        Integer telCount = smsUserMapper.selectCount(new LambdaQueryWrapper<SmsUser>()
                                .eq(SmsUser::getTel, studentInfo.getStuTel()));
                        if (telCount > 1) {
                            transactionManager.rollback(status);
                            createImportTaskDetail(studentInfo.getStuNo(), studentInfo.getStuName(), taskId, REASON_TEL_EXIST, String.valueOf(i + OFFSET_ROW));
                            taskStatus = TASK_STATUS_ERR;
                            continue;
                        }

                        // 新增学生信息
                        smsStudentInfoMapper.insert(studentInfo);

                        // 新增学生账号
                        SmsUser user = new SmsUser();
                        user.setUsername(studentInfo.getStuNo());
                        user.setRealName(studentInfo.getStuName());
                        user.setPassword(DEFAULT_PASSWORD);
                        user.setIsUse(0); // 账号未激活
                        user.setFlag(STUDENT_FLAG);
                        user.setTel(studentInfo.getStuTel());
                        smsUserMapper.insert(user);

                        addStudentUserRelation(user.getId(), studentInfo.getId(), orgIdList);

                        break;
                }

                // 提交事务
                transactionManager.commit(status);
            } catch (Exception e) {
                e.printStackTrace();
                // 回滚事务
                transactionManager.rollback(status);
            } finally {
                if (status.isNewTransaction() && !status.isCompleted()) {
                    transactionManager.commit(status);
                }
            }
        }

        // 更新任务状态未已结束
        smsImportTask.setStatus(taskStatus);
        smsImportTaskMapper.updateById(smsImportTask);

        return new AsyncResult<>(CommonResult.success());
    }

    /**
     * 创建错误记录
     *
     * @param no     学号
     * @param name   姓名
     * @param taskId 任务id
     * @param reason 错误原因
     * @param row    错误行数
     */
    private void createImportTaskDetail(String no, String name, String taskId, String reason, String row) {
        SmsImportTaskDetail smsImportTaskDetail = new SmsImportTaskDetail();
        smsImportTaskDetail.setTaskId(taskId); // 任务id
        smsImportTaskDetail.setFailReason(reason); // 错误原因
        smsImportTaskDetail.setFailName(name); // 姓名
        smsImportTaskDetail.setFailNo(no); // 学号
        smsImportTaskDetail.setFailRow(row); // 错误行数
        smsImportTaskDetailMapper.insert(smsImportTaskDetail);
    }

    /**
     * 处理账号关系
     *
     * @param userId    用户id
     * @param studentId 学生id
     * @param orgList   组织id
     */
    private void addStudentUserRelation(String userId, String studentId, @NotNull List<Integer> orgList) {
        // 处理学生与用户关系
        // 清除已存在关系
        smsUserStudentRelationMapper.delete(new LambdaQueryWrapper<SmsUserStudentRelation>()
                .and(i -> i.eq(SmsUserStudentRelation::getStuId, studentId)
                        .or().eq(SmsUserStudentRelation::getUserId, userId)));
        // 新增学生与用户关系
        SmsUserStudentRelation smsUserStudentRelation = new SmsUserStudentRelation();
        smsUserStudentRelation.setUserId(userId);
        smsUserStudentRelation.setStuId(studentId);
        smsUserStudentRelationMapper.insert(smsUserStudentRelation);

        // 处理用户与组织架构关系
        // 清除已存在关系
        smsOrgUserRelationMapper.delete(new LambdaQueryWrapper<SmsOrgUserRelation>()
                .eq(SmsOrgUserRelation::getUserId, userId));
        // 新增学生与组织关系
        for (Integer orgId : orgList) {
            SmsOrgUserRelation orgUserRelation = new SmsOrgUserRelation();
            orgUserRelation.setOrgId(orgId.toString());
            orgUserRelation.setUserId(userId);
            smsOrgUserRelationMapper.insert(orgUserRelation);
        }

        // 处理用户与角色关系
        // 清除已存在关系
        smsUserRoleRelationMapper.delete(new LambdaQueryWrapper<SmsUserRoleRelation>()
                .eq(SmsUserRoleRelation::getUserId, userId));
        // 新增用户与角色关系
        SmsUserRoleRelation roleRelation = new SmsUserRoleRelation();
        roleRelation.setRoleId(String.valueOf(ROLE_STUDENT));
        roleRelation.setUserId(userId);
        smsUserRoleRelationMapper.insert(roleRelation);

        // 添加新生收费项状态
        categoryItemUtil.addCategoryItem(userId);
    }

    @Override
    public ResponseResult getPersonalInfoStatus(String userId) {
        SmsPersonalInfoStatusResp smsPersonalInfoStatusResp = new SmsPersonalInfoStatusResp();
        SmsUserStudentRelation studentRelation = smsUserStudentRelationMapper.selectOne(new LambdaQueryWrapper<SmsUserStudentRelation>()
                .eq(SmsUserStudentRelation::getUserId, userId));
        if (isNullOrEmpty(studentRelation)) {
            return CommonResult.failed(CommonCodeEnum.STUDENT_NOT_EXIST);
        }

        SmsStudentInfo studentInfo = smsStudentInfoMapper.selectById(studentRelation.getStuId());
        if (isNullOrEmpty(studentInfo)) {
            return CommonResult.failed(CommonCodeEnum.STUDENT_NOT_EXIST);
        }
        //学生基本信息
        String stuName = studentInfo.getStuName();
        String stuSex = studentInfo.getStuSex();
        Date stuBirth = studentInfo.getStuBirth();
        String stuIdCard = studentInfo.getStuIdCard();
        String stuNativePlace = studentInfo.getStuNativePlace();//籍贯
        String stuNationCode = studentInfo.getStuNationCode();//民族
        String stuPoliticCountenanceCode = studentInfo.getStuPoliticCountenanceCode();//政治面貌
        String stuAddr = studentInfo.getStuAddr();//家庭住址
        smsPersonalInfoStatusResp.setStuBasicInfo(!isNullOrEmpty(stuName, stuSex, stuBirth, stuIdCard, stuNativePlace, stuNationCode, stuPoliticCountenanceCode));
        //健康信息
        String healthStatus = studentInfo.getHealthStatus();
        if (isNullOrEmpty(healthStatus)) {
            smsPersonalInfoStatusResp.setStuHealthInfo(false);
        } else {
            if (healthStatus.equals(STUDENT_NOT_HEALTH)) {
                String healthDetail = studentInfo.getHealthDetail();
                smsPersonalInfoStatusResp.setStuHealthInfo(!isNullOrEmpty(healthDetail));
            }
        }
        //家庭地址
        smsPersonalInfoStatusResp.setStuAddressInfo(!isNullOrEmpty(stuAddr));
        //成员信息
        String stuParentInfo = studentInfo.getStuParentInfo();
        smsPersonalInfoStatusResp.setStuParentInfo(!isNullOrEmpty(stuParentInfo));
        //经济信息
        smsPersonalInfoStatusResp.setStuEconomyInfo(!isNullOrEmpty(studentInfo.getEconomyStatus()));
        return CommonResult.success(smsPersonalInfoStatusResp);
    }

    @Override
    public ResponseResult listStuInfoByMajor(Integer pageNum, Integer pageSize, String gradeId, Integer classId) {
        List<Integer> classIdList = new ArrayList<>();

        if (isNullOrEmpty(classId)) {
            // 获取当前年级下所有班级
            List<SmsOrgStructure> classOrgList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                    .eq(SmsOrgStructure::getParentId, gradeId)
                    .eq(SmsOrgStructure::getLevel, 6));
            if (classOrgList.isEmpty()) {
                return CommonResult.failed(CommonCodeEnum.WNS_CLASS_NOT_EXIST);
            }
            classIdList = classOrgList.stream().map(SmsOrgStructure::getId).collect(Collectors.toList());
        } else {
            classIdList.add(classId);
        }

        // 获取所有用户id
        List<SmsOrgUserRelation> userRelationList = smsOrgUserRelationMapper.selectList(new LambdaQueryWrapper<SmsOrgUserRelation>()
                .in(SmsOrgUserRelation::getOrgId, classIdList));
        List<String> userIdList = userRelationList.stream().map(SmsOrgUserRelation::getUserId).distinct().collect(Collectors.toList());

        // 根据用户id获取stuId
        List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                .in(SmsUserStudentRelation::getUserId, userIdList));
        List<String> stuIdList = userStudentRelationList.stream().map(SmsUserStudentRelation::getStuId).distinct().collect(Collectors.toList());

        // 查询学生信息
        Page<SmsStudentInfo> page = new Page<>(pageNum, pageSize);
        smsStudentInfoMapper.selectPage(page, new LambdaQueryWrapper<SmsStudentInfo>().in(SmsStudentInfo::getId, stuIdList));
        List<SmsStudentInfoResp> studentInfoRespList = page.getRecords().stream().map(studentInfo -> {
            SmsStudentInfoResp studentInfoResp = new SmsStudentInfoResp();
            BeanUtils.copyProperties(studentInfo, studentInfoResp);
            return studentInfoResp;
        }).collect(Collectors.toList());

        return CommonResult.success(studentInfoRespList, (int) page.getTotal());
    }

    @Override
    public ResponseResult listClassByGrade(String grade, String majorId) {
        // 获取年级
        List<SmsOrgStructure> gradeOrgList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                .like(SmsOrgStructure::getOrgName, grade)
                .eq(SmsOrgStructure::getLevel, 5)
                .eq(SmsOrgStructure::getParentId, majorId)
                .orderByDesc(SmsOrgStructure::getCreateTime));

        if (gradeOrgList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.WNS_GRADE_NOT_EXIST);
        }

        // 获取当前年级下所有班级
        List<SmsOrgStructure> classOrgList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                .eq(SmsOrgStructure::getParentId, gradeOrgList.get(0).getId()));

        List<OrgStructureResp> collect = classOrgList.stream().map(classOrg -> {
            OrgStructureResp orgResp = new OrgStructureResp();
            BeanUtils.copyProperties(classOrg, orgResp);
            return orgResp;
        }).collect(Collectors.toList());

        return CommonResult.success(collect, collect.size());
    }

    @Override
    @Transactional
    public ResponseResult classifyStu(ClassifyStuReq classifyStuReq) {
        if (isNullOrEmpty(classifyStuReq.getGradeId(), classifyStuReq.getClassNum())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        // 校验年级是否存在
        SmsOrgStructure gradeOrg = smsOrgStructureMapper.selectById(classifyStuReq.getGradeId());
        if (gradeOrg == null || !gradeOrg.getLevel().equals(String.valueOf(5))) {
            return CommonResult.failed(CommonCodeEnum.WNS_GRADE_NOT_EXIST);
        }

        // 校验班级是否存在
        List<SmsOrgStructure> classOrgList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                .eq(SmsOrgStructure::getParentId, classifyStuReq.getGradeId())
                .eq(SmsOrgStructure::getLevel, 6));
        if (classOrgList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.WNS_CLASS_NOT_EXIST);
        }

        // 收集该专业男女生userId
        List<String> boyUserIdList = new ArrayList<>();
        List<String> girlUserIdList = new ArrayList<>();
        for (SmsOrgStructure classOrg : classOrgList) {
            // 获取当前班级学生 userIdList
            List<SmsOrgUserRelation> userRelationList = smsOrgUserRelationMapper.selectList(new LambdaQueryWrapper<SmsOrgUserRelation>()
                    .eq(SmsOrgUserRelation::getOrgId, classOrg.getId()));
            List<String> userIdList = userRelationList.stream().map(SmsOrgUserRelation::getUserId).distinct().collect(Collectors.toList());

            // 根据 userIdList 获取所有学生信息
            List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                    .in(SmsUserStudentRelation::getUserId, userIdList));
            List<String> stuIdList = userStudentRelationList.stream().map(SmsUserStudentRelation::getStuId).distinct().collect(Collectors.toList());
            List<SmsStudentInfo> studentInfoList = smsStudentInfoMapper.selectBatchIds(stuIdList);

            // 收集男生userId信息
            List<SmsStudentInfo> classBoyInfoList = studentInfoList.stream().filter(studentInfo -> studentInfo.getStuSex().equals("男")).collect(Collectors.toList());
            if (!classBoyInfoList.isEmpty()) {
                List<String> classBoyIdList = classBoyInfoList.stream().map(SmsStudentInfo::getId).collect(Collectors.toList());
                List<String> classBoyUserIdList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                                .in(SmsUserStudentRelation::getStuId, classBoyIdList))
                        .stream().map(SmsUserStudentRelation::getUserId).collect(Collectors.toList());
                boyUserIdList.addAll(classBoyUserIdList);
            }
            // 收集女生userId信息
            List<SmsStudentInfo> classGrilInfoList = studentInfoList.stream().filter(studentInfo -> studentInfo.getStuSex().equals("女")).collect(Collectors.toList());
            if (!classGrilInfoList.isEmpty()) {
                List<String> classGrilIdList = classGrilInfoList.stream().map(SmsStudentInfo::getId).collect(Collectors.toList());
                List<String> classGrilUserIdList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                                .in(SmsUserStudentRelation::getStuId, classGrilIdList))
                        .stream().map(SmsUserStudentRelation::getUserId).collect(Collectors.toList());
                girlUserIdList.addAll(classGrilUserIdList);
            }

            // 根据 stuIdList 获取所有学生 userId
            List<String> delStuUserIdList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>().in(SmsUserStudentRelation::getStuId, stuIdList))
                    .stream().map(SmsUserStudentRelation::getUserId).distinct().collect(Collectors.toList());
            if (!delStuUserIdList.isEmpty()) {
                // 删除原有user-org关系
                smsOrgUserRelationMapper.delete(new LambdaQueryWrapper<SmsOrgUserRelation>()
                        .in(SmsOrgUserRelation::getUserId, delStuUserIdList));
            }
        }

        // 获取专业名
        SmsOrgStructure majorOrg = smsOrgStructureMapper.selectById(gradeOrg.getParentId());

        // 删除原有班级信息
        List<SmsOrgStructure> classList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                .eq(SmsOrgStructure::getParentId, classifyStuReq.getGradeId())
                .eq(SmsOrgStructure::getLevel, 6));
        List<Integer> classIdList = classList.stream().map(SmsOrgStructure::getId).collect(Collectors.toList());

        for (Integer classId : classIdList) {
            // 如果有还未结束的计划包含本班,抛出异常
            List<SmsWnsChargePlan> planList = smsWnsChargePlanMapper.selectList(new LambdaQueryWrapper<SmsWnsChargePlan>()
                    .eq(SmsWnsChargePlan::getRangeType, ChargePlanConstant.CHARGE_PLAN_RANGE_TYPE_CLASS)
                    .ge(SmsWnsChargePlan::getEndTime, new Date()));
            for (SmsWnsChargePlan plan : planList) {
                List<String> rangeClassIdList = JSON.parseArray(plan.getIdList(), String.class);
                if (rangeClassIdList.contains(String.valueOf(classId))) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.WNS_PLAN_CONTAINS_CLASS));
                }
            }
        }
        smsOrgStructureMapper.deleteBatchIds(classIdList);

        // 创建班级并进行分班
        int everyClassBoyNum = (int) Math.round((double) boyUserIdList.size() / classifyStuReq.getClassNum()); // 每班男生数
        int everyClassGirlNum = (int) Math.round((double) girlUserIdList.size() / classifyStuReq.getClassNum()); // 每班女生数
        List<SmsOrgUserRelation> orgUserRelationNeedSaveList = new ArrayList<>();
        for (int num = 1; num <= classifyStuReq.getClassNum(); num++) {
            // 构造班级名称: 年级 + 专业 + num + 班 (例: 2024级艺术设计1班)
            String className = gradeOrg.getOrgName() + majorOrg.getOrgName() + num + "班";

            // 创建班级
            SmsOrgStructure classOrg = new SmsOrgStructure();
            classOrg.setParentId(gradeOrg.getId()); // 年级id
            classOrg.setOrgName(className); // 班级名称
            classOrg.setLevel(String.valueOf(Integer.parseInt(gradeOrg.getLevel()) + 1)); // 层级 = 年级层级 + 1
            classOrg.setCanDeleted(0); // 不能删除
            smsOrgStructureMapper.insert(classOrg);

            // 截取本班男生女生
            List<String> classBoyIdList;
            List<String> classGrilIdList;
            if (num == classifyStuReq.getClassNum()) { // 最后一次循环
                classBoyIdList = boyUserIdList.subList(everyClassBoyNum * (num - 1), boyUserIdList.size());
                classGrilIdList = girlUserIdList.subList(everyClassGirlNum * (num - 1), girlUserIdList.size());
            } else {
                classBoyIdList = boyUserIdList.subList(everyClassBoyNum * (num - 1), everyClassBoyNum * num);
                classGrilIdList = girlUserIdList.subList(everyClassGirlNum * (num - 1), everyClassGirlNum * num);
            }
            // 设置男生班级
            for (String boyUserId : classBoyIdList) {
                SmsOrgUserRelation orgUserRelation = new SmsOrgUserRelation();
                orgUserRelation.setUserId(boyUserId);
                orgUserRelation.setOrgId(String.valueOf(classOrg.getId()));
//                smsOrgUserRelationMapper.insert(orgUserRelation);
                orgUserRelationNeedSaveList.add(orgUserRelation);
            }

            // 设置女生班级
            for (String girlUserId : classGrilIdList) {
                SmsOrgUserRelation orgUserRelation = new SmsOrgUserRelation();
                orgUserRelation.setUserId(girlUserId);
                orgUserRelation.setOrgId(String.valueOf(classOrg.getId()));
//                smsOrgUserRelationMapper.insert(orgUserRelation);
                orgUserRelationNeedSaveList.add(orgUserRelation);
            }

            // 修改学生班级信息
            List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationService.list(new LambdaQueryWrapper<SmsUserStudentRelation>()
                    .and(i -> i.in(!classBoyIdList.isEmpty(), SmsUserStudentRelation::getUserId, classBoyIdList)
                            .or()
                            .in(!classGrilIdList.isEmpty(), SmsUserStudentRelation::getUserId, classGrilIdList)));
            List<String> stuNeedUpdIdList = userStudentRelationList.stream().map(SmsUserStudentRelation::getStuId).collect(Collectors.toList());
            SmsStudentInfo studentInfo = new SmsStudentInfo();
            studentInfo.setStuClass(className);
            smsStudentInfoMapper.update(studentInfo, new LambdaQueryWrapper<SmsStudentInfo>()
                    .in(SmsStudentInfo::getId, stuNeedUpdIdList));
        }

        // 批量保存学生班级信息
        smsOrgUserRelationService.saveBatch(orgUserRelationNeedSaveList);

        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult changeClass(ChangeClassReq changeClassReq) {
        if (isNullOrEmpty(changeClassReq.getClassId(), changeClassReq.getStuIdList())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        // 校验班级是否存在
        SmsOrgStructure classOrg = smsOrgStructureMapper.selectById(changeClassReq.getClassId());
        if (classOrg == null || !classOrg.getLevel().equals("6")) {
            return CommonResult.failed(CommonCodeEnum.WNS_CLASS_NOT_EXIST);
        }

        // 如果有还未结束的计划包含本班,抛出异常
//        List<SmsWnsChargePlan> planList = smsWnsChargePlanMapper.selectList(new LambdaQueryWrapper<SmsWnsChargePlan>()
//                .eq(SmsWnsChargePlan::getRangeType, ChargePlanConstant.CHARGE_PLAN_RANGE_TYPE_CLASS)
//                .ge(SmsWnsChargePlan::getEndTime, new Date()));
//        for (SmsWnsChargePlan plan : planList) {
//            List<String> rangeClassIdList = JSON.parseArray(plan.getIdList(), String.class);
//            if (rangeClassIdList.contains(changeClassReq.getClassId())) {
//                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.WNS_PLAN_CONTAINS_CLASS));
//            }
//        }

        // 根据学生id获取userId
//        List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
//                .in(SmsUserStudentRelation::getStuId, changeClassReq.getStuIdList()));
//        if (userStudentRelationList.isEmpty()) {
//            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
//        }
//        List<String> userIdList = userStudentRelationList.stream().map(SmsUserStudentRelation::getUserId).distinct().collect(Collectors.toList());


        List<String> userIdList = new ArrayList<>();
        List<SmsStuOrgUpdateHistory> stuOrgUpdateHistoryList = new ArrayList<>(); // 转班历史
        List<SmsOrgUserRelation> orgUserRelationNeedSaveList = new ArrayList<>(); // 新增班级信息
        for (String stuId : changeClassReq.getStuIdList()) {
            String userId = orgUserStuUtil.getUserIdByStuId(stuId);
            if (isNullOrEmpty(userId)) {
                continue;
            }

            // 收集userId
            userIdList.add(userId);

            List<String> orgIdList = orgUserStuUtil.getOrgIdListByUserId(userId);
            if (!orgIdList.isEmpty()) {
                // 保存转班历史
                for (String orgId : orgIdList) {
                    SmsOrgStructure orgStructure = smsOrgStructureMapper.selectById(orgId);
                    SmsStuOrgUpdateHistory stuOrgUpdateHistory = new SmsStuOrgUpdateHistory();
                    stuOrgUpdateHistory.setUserId(userId);
                    stuOrgUpdateHistory.setStuId(stuId);
                    stuOrgUpdateHistory.setOldOrgId(Integer.valueOf(orgId));
                    stuOrgUpdateHistory.setOldOrgName(orgStructure.getOrgName());
                    stuOrgUpdateHistory.setNewOrgId(classOrg.getId());
                    stuOrgUpdateHistory.setNewOrgName(classOrg.getOrgName());
                    stuOrgUpdateHistoryList.add(stuOrgUpdateHistory);
                }
            }

            // 新增班级信息
            SmsOrgUserRelation orgUserRelation = new SmsOrgUserRelation();
            orgUserRelation.setUserId(userId);
            orgUserRelation.setOrgId(String.valueOf(classOrg.getId()));
            orgUserRelationNeedSaveList.add(orgUserRelation);
        }

        // 保存转班历史
        if (!stuOrgUpdateHistoryList.isEmpty()) {
            smsStuOrgUpdateHistoryService.saveBatch(stuOrgUpdateHistoryList);
        }

        // 删除原有班级
        smsOrgUserRelationMapper.delete(new LambdaQueryWrapper<SmsOrgUserRelation>()
                .in(SmsOrgUserRelation::getUserId, userIdList));

        // 保存新班级信息
        smsOrgUserRelationService.saveBatch(orgUserRelationNeedSaveList);

        // 设置学生班级信息
        SmsStudentInfo studentInfoNeedUpd = new SmsStudentInfo();
        studentInfoNeedUpd.setStuClass(classOrg.getOrgName());

        // 设置年级
        SmsOrgStructure gradeOrg = smsOrgStructureMapper.selectById(classOrg.getParentId());
        if (gradeOrg != null) {
            studentInfoNeedUpd.setStuGrade(gradeOrg.getOrgName());

            // 设置专业
            SmsOrgStructure majorOrg = smsOrgStructureMapper.selectById(gradeOrg.getParentId());
            if (majorOrg != null) {
                studentInfoNeedUpd.setStuMajor(majorOrg.getOrgName());

                // 设置学院
                SmsOrgStructure collegeOrg = smsOrgStructureMapper.selectById(majorOrg.getParentId());
                if (collegeOrg != null) {
                    studentInfoNeedUpd.setStuCollege(collegeOrg.getOrgName());
                }
            }
        }

        // 修改学生组织信息
        smsStudentInfoMapper.update(studentInfoNeedUpd, new LambdaQueryWrapper<SmsStudentInfo>()
                .in(SmsStudentInfo::getId, changeClassReq.getStuIdList()));

        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult delNewStu(SmsWnsIdListReq idListReq) {
        List<String> stuIdList = idListReq.getIdList();
        if (stuIdList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                .in(SmsUserStudentRelation::getStuId, stuIdList));
        if (userStudentRelationList.isEmpty()) {
            smsStudentInfoMapper.deleteBatchIds(stuIdList);
            return CommonResult.success();
        }

        // 获取用户id集合
        List<String> userIdList = userStudentRelationList.stream().map(SmsUserStudentRelation::getUserId).distinct().collect(Collectors.toList());

        // OrgUserRelation
        smsOrgUserRelationMapper.delete(new LambdaQueryWrapper<SmsOrgUserRelation>()
                .in(SmsOrgUserRelation::getUserId, userIdList));

        // UserRoleRelation
        smsUserRoleRelationMapper.delete(new LambdaQueryWrapper<SmsUserRoleRelation>()
                .in(SmsUserRoleRelation::getUserId, userIdList));

        // UserStudentRelation
        smsUserStudentRelationMapper.delete(new LambdaQueryWrapper<SmsUserStudentRelation>()
                .in(SmsUserStudentRelation::getStuId, stuIdList));

        // StudentInfo
        smsStudentInfoMapper.deleteBatchIds(stuIdList);

        // User
        smsUserMapper.deleteBatchIds(userIdList);

        return CommonResult.success();
    }

    @Override
    public ResponseResult listAllMajorByGrade(String grade) {
        List<SmsOrgStructureResp> orgStructureRespList = new ArrayList<>();

        // 查询所有年级
        List<SmsOrgStructure> gradeOrgList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                .like(SmsOrgStructure::getOrgName, grade)
                .eq(SmsOrgStructure::getLevel, 5)
                .orderByDesc(SmsOrgStructure::getCreateTime));
        if (gradeOrgList.isEmpty()) {
            return CommonResult.success(orgStructureRespList);
        }

        // 收集专业信息
        List<Integer> majorOrgIdList = gradeOrgList.stream().map(SmsOrgStructure::getParentId).collect(Collectors.toList());
        List<SmsOrgStructure> majorOrgList = smsOrgStructureMapper.selectBatchIds(majorOrgIdList);
        if (majorOrgList.isEmpty()) {
            return CommonResult.success(orgStructureRespList);
        }

        List<SmsOrgStructureResp> majorOrgRespList = majorOrgList.stream().map(majorOrg -> {
            SmsOrgStructureResp majorOrgResp = new SmsOrgStructureResp();
            BeanUtils.copyProperties(majorOrg, majorOrgResp);
            return majorOrgResp;
        }).collect(Collectors.toList());
        orgStructureRespList.addAll(majorOrgRespList);

        // 收集院系信息
        List<Integer> collegeOrgIdList = majorOrgList.stream().map(SmsOrgStructure::getParentId).collect(Collectors.toList());
        List<SmsOrgStructure> collegeOrgList = smsOrgStructureMapper.selectBatchIds(collegeOrgIdList);
        if (collegeOrgList.isEmpty()) {
            return CommonResult.success(orgStructureRespList);
        }

        List<SmsOrgStructureResp> collegeOrgRespList = collegeOrgList.stream().map(collegeOrg -> {
            SmsOrgStructureResp collegeOrgResp = new SmsOrgStructureResp();
            BeanUtils.copyProperties(collegeOrg, collegeOrgResp);
            return collegeOrgResp;
        }).collect(Collectors.toList());
        orgStructureRespList.addAll(collegeOrgRespList);

        return CommonResult.success(orgStructureRespList, majorOrgRespList.size());
    }

    @Override
    public ResponseResult listAllClassByGrade(String grade) {
        List<SmsOrgStructureResp> orgStructureRespList = new ArrayList<>();

        // 查询所有年级
        List<SmsOrgStructure> gradeOrgList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                .like(SmsOrgStructure::getOrgName, grade)
                .eq(SmsOrgStructure::getLevel, 5)
                .orderByDesc(SmsOrgStructure::getCreateTime));
        if (gradeOrgList.isEmpty()) {
            return CommonResult.success(orgStructureRespList);
        }

        // 收集专业信息
        List<Integer> majorOrgIdList = gradeOrgList.stream().map(SmsOrgStructure::getParentId).collect(Collectors.toList());
        List<SmsOrgStructure> majorOrgList = smsOrgStructureMapper.selectBatchIds(majorOrgIdList);
        if (majorOrgList.isEmpty()) {
            return CommonResult.success(orgStructureRespList);
        }

        List<SmsOrgStructureResp> majorOrgRespList = majorOrgList.stream().map(majorOrg -> {
            SmsOrgStructureResp majorOrgResp = new SmsOrgStructureResp();
            BeanUtils.copyProperties(majorOrg, majorOrgResp);
            return majorOrgResp;
        }).collect(Collectors.toList());
        orgStructureRespList.addAll(majorOrgRespList);

        // 收集院系信息
        List<Integer> collegeOrgIdList = majorOrgList.stream().map(SmsOrgStructure::getParentId).collect(Collectors.toList());
        List<SmsOrgStructure> collegeOrgList = smsOrgStructureMapper.selectBatchIds(collegeOrgIdList);
        if (collegeOrgList.isEmpty()) {
            return CommonResult.success(orgStructureRespList);
        }

        List<SmsOrgStructureResp> collegeOrgRespList = collegeOrgList.stream().map(collegeOrg -> {
            SmsOrgStructureResp collegeOrgResp = new SmsOrgStructureResp();
            BeanUtils.copyProperties(collegeOrg, collegeOrgResp);
            return collegeOrgResp;
        }).collect(Collectors.toList());
        orgStructureRespList.addAll(collegeOrgRespList);

        // 收集班级信息
        for (SmsOrgStructure gradeOrg : gradeOrgList) {
            List<SmsOrgStructure> classOrgList = smsOrgStructureMapper.selectList(new LambdaQueryWrapper<SmsOrgStructure>()
                    .eq(SmsOrgStructure::getParentId, gradeOrg.getId()));
            if (!classOrgList.isEmpty()) {
                List<SmsOrgStructureResp> classOrgRespList = classOrgList.stream().map(classOrg -> {
                    SmsOrgStructureResp classOrgResp = new SmsOrgStructureResp();
                    BeanUtils.copyProperties(classOrg, classOrgResp);
                    classOrgResp.setParentId(gradeOrg.getParentId());
                    return classOrgResp;
                }).collect(Collectors.toList());
                orgStructureRespList.addAll(classOrgRespList);
            }
        }

        return CommonResult.success(orgStructureRespList, majorOrgRespList.size());
    }

    @Override
    public ResponseResult listNewStuInfo(Integer pageNum, Integer pageSize, String searchStr) {
        LambdaQueryWrapper<SmsUser> queryWrapper = new LambdaQueryWrapper<SmsUser>()
                .eq(SmsUser::getIsUse, 0) // 新生(未激活)
                .orderByDesc(SmsUser::getCreateTime);

        if (!isNullOrEmpty(searchStr)) {
            List<SmsStudentInfo> studentInfoList = smsStudentInfoMapper.selectList(new LambdaQueryWrapper<SmsStudentInfo>()
                    .like(SmsStudentInfo::getStuNo, searchStr).or()
                    .like(SmsStudentInfo::getStuName, searchStr).or()
                    .like(SmsStudentInfo::getStuTel, searchStr).or()
                    .like(SmsStudentInfo::getStuIdCard, searchStr).or()
                    .like(SmsStudentInfo::getStuSex, searchStr).or()
                    .like(SmsStudentInfo::getStuCollege, searchStr).or()
                    .like(SmsStudentInfo::getStuMajor, searchStr).or()
                    .like(SmsStudentInfo::getStuGrade, searchStr).or()
                    .like(SmsStudentInfo::getStuClass, searchStr).or()
                    .like(SmsStudentInfo::getStuNation, searchStr).or()
                    .like(SmsStudentInfo::getStuNativePlace, searchStr));
            if (studentInfoList.isEmpty()) {
                queryWrapper.in(SmsUser::getId, "");
            } else {
                List<String> stuIdList = studentInfoList.stream().map(SmsStudentInfo::getId).collect(Collectors.toList());
                List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                        .in(SmsUserStudentRelation::getStuId, stuIdList));
                List<String> userIdList = userStudentRelationList.stream().map(SmsUserStudentRelation::getUserId).collect(Collectors.toList());
                queryWrapper.in(SmsUser::getId, userIdList);
            }
        }

        Page<SmsUser> page = new Page<>(pageNum, pageSize);
        smsUserMapper.selectPage(page, queryWrapper);
        List<UserInfoResp> userInfoRespList = page.getRecords().stream().map(user -> {
            UserInfoResp userInfoResp = new UserInfoResp();
            BeanUtils.copyProperties(user, userInfoResp);
            return userInfoResp;
        }).collect(Collectors.toList());

        return CommonResult.success(userInfoRespList, (int) page.getTotal());
    }

    @Override
    public ResponseResult newStuInfoDetail(String userId) {
        SmsUser user = smsUserMapper.selectById(userId);
        if (user == null) {
            return CommonResult.failed(CommonCodeEnum.USER_NOT_EXIST);
        }

        List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                .eq(SmsUserStudentRelation::getUserId, userId));
        if (userStudentRelationList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.STUDENT_NOT_EXIST);
        }

        SmsStudentInfo studentInfo = smsStudentInfoMapper.selectById(userStudentRelationList.get(0).getStuId());
        if (studentInfo == null) {
            return CommonResult.failed(CommonCodeEnum.STUDENT_NOT_EXIST);
        }

        // 返回学生信息及现场照片
        List<SmsWnsStudentCardInformation> studentCardInformationList = smsWnsStudentCardInformationMapper.selectList(new LambdaQueryWrapper<SmsWnsStudentCardInformation>()
                .eq(SmsWnsStudentCardInformation::getUserId, userId));
        SmsWnsStudentCardInformationResp studentCardInformationResp = new SmsWnsStudentCardInformationResp();
        if (!studentCardInformationList.isEmpty()) {
            SmsWnsStudentCardInformation studentCardInformation = studentCardInformationList.get(0);
            BeanUtils.copyProperties(studentCardInformation, studentCardInformationResp);
        }
        studentCardInformationResp.setUserId(userId);
        studentCardInformationResp.setStudentInfo(studentInfo);

        return CommonResult.success(studentCardInformationResp);
    }

    @Override
    @Transactional
    public ResponseResult uploadSitePic(SmsWnsStudentCardInformationReq cardInformationReq) {
        if (isNullOrEmpty(cardInformationReq.getUserId(), cardInformationReq.getSitePic())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsUser user = smsUserMapper.selectById(cardInformationReq.getUserId());
        if (user == null) {
            return CommonResult.failed(CommonCodeEnum.USER_NOT_EXIST);
        }

        RecognizeFaceResp recognizeFaceResp = AliyunImgUtil.recognizeFace(cardInformationReq.getSitePic());
        if (recognizeFaceResp == null) {
            return CommonResult.failed(CommonCodeEnum.WNS_STUDENT_SITE_PICTURE_ILLEGAL);
        }

        // 校验照片质量
        if (recognizeFaceResp.getScoreQualities() < 80 ||
                recognizeFaceResp.getBlurQualities() < 80 ||
                recognizeFaceResp.getPoseQualities() < 80 ||
                recognizeFaceResp.getIlluQualities() < 80 ||
                recognizeFaceResp.getGlassQualities() < 80 ||
                recognizeFaceResp.getMaskQualities() < 80 ||
                recognizeFaceResp.getFnfQualities() < 80 ||
                recognizeFaceResp.getNoiseQualities() < 80) {
            return CommonResult.failed(CommonCodeEnum.WNS_STUDENT_SITE_PICTURE_ILLEGAL);
        }

        // 查询三证信息
        List<SmsWnsStudentCardInformation> studentCardInformationList = smsWnsStudentCardInformationMapper.selectList(new LambdaQueryWrapper<SmsWnsStudentCardInformation>()
                .eq(SmsWnsStudentCardInformation::getUserId, cardInformationReq.getUserId()));
        if (studentCardInformationList.isEmpty()) { // 不存在
            List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                    .eq(SmsUserStudentRelation::getUserId, cardInformationReq.getUserId()));
            if (userStudentRelationList.isEmpty()) {
                return CommonResult.failed(CommonCodeEnum.STUDENT_NOT_EXIST);
            }

            // 保存现场照片
            SmsWnsStudentCardInformation studentCardInformation = new SmsWnsStudentCardInformation();
            studentCardInformation.setUserId(cardInformationReq.getUserId());
            studentCardInformation.setStuId(userStudentRelationList.get(0).getStuId());
            studentCardInformation.setSitePic(cardInformationReq.getSitePic());
            smsWnsStudentCardInformationMapper.insert(studentCardInformation);
        } else { // 存在
            SmsWnsStudentCardInformation studentCardInformation = studentCardInformationList.get(0);
            studentCardInformation.setSitePic(cardInformationReq.getSitePic());

            // 修改现场照片
            smsWnsStudentCardInformationMapper.updateById(studentCardInformation);
        }

        return CommonResult.success();
    }

    @Override
    public ResponseResult newStuInfoDetailByIdCard(String idCard) {
        List<SmsStudentInfo> studentInfoList = smsStudentInfoMapper.selectList(new LambdaQueryWrapper<SmsStudentInfo>()
                .eq(SmsStudentInfo::getStuIdCard, idCard));
        if (studentInfoList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.STUDENT_NOT_EXIST);
        }

        SmsStudentInfo studentInfo = studentInfoList.get(0);
        List<SmsWnsStudentCardInformation> studentCardInformationList = smsWnsStudentCardInformationMapper.selectList(new LambdaQueryWrapper<SmsWnsStudentCardInformation>()
                .eq(SmsWnsStudentCardInformation::getStuId, studentInfo.getId()));

        // 返回学生信息及三证照片
        SmsWnsStudentCardInformationResp studentCardInformationResp = new SmsWnsStudentCardInformationResp();
        SmsWnsStudentCardInformation studentCardInformation;
        if (!studentCardInformationList.isEmpty()) { // 存在三证信息
            studentCardInformation = studentCardInformationList.get(0);
        } else { // 不存在
            // 保存现场照片
            studentCardInformation = new SmsWnsStudentCardInformation();
            // 设置userId
            List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                    .eq(SmsUserStudentRelation::getStuId, studentInfo.getId()));
            studentCardInformation.setUserId(userStudentRelationList.get(0).getUserId());

            studentCardInformation.setStuId(studentInfo.getId());
            smsWnsStudentCardInformationMapper.insert(studentCardInformation);
        }
        BeanUtils.copyProperties(studentCardInformation, studentCardInformationResp);
        studentCardInformationResp.setStudentInfo(studentInfo);

        return CommonResult.success(studentCardInformationResp);
    }

    @Override
    @Transactional
    public ResponseResult approveNewStuInfo(SmsWnsStudentCardInformationReq cardInformationReq) {
        if (isNullOrEmpty(cardInformationReq.getId(), cardInformationReq.getType())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        if (!STUDENT_INFO_APPROVE_TYPE_LIST.contains(cardInformationReq.getType())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsWnsStudentCardInformation studentCardInformation = smsWnsStudentCardInformationMapper.selectById(cardInformationReq.getId());
        if (studentCardInformation == null // 三证信息不存在
                || isNullOrEmpty(studentCardInformation.getChsiPic(), studentCardInformation.getSitePic()) // 学籍或现场照片为空
                || (isNullOrEmpty(studentCardInformation.getIdCardPic()) && isNullOrEmpty(cardInformationReq.getIdCardPic()))) { // 数据库中身份证和前端传入身份证均为空
            return CommonResult.failed(CommonCodeEnum.WNS_STUDENT_CARD_INFORMATION_NOT_EXIST);
        }

        if (!isNullOrEmpty(cardInformationReq.getIdCardPic() == null)) {
            // 保存身份证信息
            studentCardInformation.setIdCardPic(cardInformationReq.getIdCardPic());
            smsWnsStudentCardInformationMapper.updateById(studentCardInformation);
        }

        // 系统比对通过
        if (cardInformationReq.getType() == STUDENT_INFO_APPROVE_TYPE_SYSTEM_PASS) {
            // 学信网照片与身份证照片对比
            CompareFaceResp compareFaceResp1 = AliyunImgUtil.CompareFaceUrl(studentCardInformation.getChsiPic(), studentCardInformation.getIdCardPic());
            if (compareFaceResp1 == null) {
                return CommonResult.failed(CommonCodeEnum.WNS_STUDENT_PICTURE_COMPARE_FAIL);
            }
            if (compareFaceResp1.getConfidence() < 80) {
                return CommonResult.failed(CommonCodeEnum.WNS_STUDENT_PICTURE_NOT_SAME_PEOPLE);
            }

            // 身份证照片与现场照片对比
            CompareFaceResp compareFaceResp2 = AliyunImgUtil.CompareFaceUrl(studentCardInformation.getIdCardPic(), studentCardInformation.getSitePic());
            if (compareFaceResp2 == null) {
                return CommonResult.failed(CommonCodeEnum.WNS_STUDENT_PICTURE_COMPARE_FAIL);
            }
            if (compareFaceResp2.getConfidence() < 80) {
                return CommonResult.failed(CommonCodeEnum.WNS_STUDENT_PICTURE_NOT_SAME_PEOPLE);
            }
        }

        // 查询到流程:招生就业处报道
        List<SmsWnsRegistrationProcessDetail> processDetailList = this.list(new LambdaQueryWrapper<SmsWnsRegistrationProcessDetail>()
                .eq(SmsWnsRegistrationProcessDetail::getUserId, studentCardInformation.getUserId())
                .eq(SmsWnsRegistrationProcessDetail::getSort, REGISTRATION_PROCESS_DETAIL_SORT_ONE));
        SmsWnsRegistrationProcessDetail detail = processDetailList.get(0);
        if (cardInformationReq.getType() == STUDENT_INFO_APPROVE_TYPE_DENY) { // 拒绝
            detail.setStatus(REGISTRATION_PROCESS_DETAIL_STATUS_FAIL);
        } else { // 通过
            // 记录学生身份证照片
            studentCardInformation.setIdCardPic(cardInformationReq.getIdCardPic());
            smsWnsStudentCardInformationMapper.updateById(studentCardInformation);

            detail.setStatus(REGISTRATION_PROCESS_DETAIL_STATUS_END);
        }

        this.updateById(detail);

        return CommonResult.success();
    }

    @Override
    @Async
    public Future<ResponseResult> batchAddChsiPic(SmsWnsChsiPicBatchAddReq req, String userId) {
        if (isNullOrEmpty(req.getType()) || !UPDATE_TYPE_LIST.contains(req.getType())) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        List<StuIdChsiPicReq> stuIdChsiPicReqList = req.getStuIdChsiPicReqList();
        if (stuIdChsiPicReqList == null || stuIdChsiPicReqList.isEmpty()) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }
        List<ChsiPicReq> chsiPicReqList = req.getChsiPicReqList();
        if (chsiPicReqList == null || chsiPicReqList.isEmpty()) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }

        // 创建导入任务
        SmsImportTask smsImportTask = new SmsImportTask();
        smsImportTask.setTaskName(TaskNameExample.TASK_NAME_STUDENT_CHSI_PICTURE_IMPORT);
        smsImportTask.setUserId(userId);
        smsImportTask.setStatus(TASK_STATUS_DOING); // 任务状态 0:进行中
        smsImportTask.setTaskType(TaskTypeConstant.TASK_TYPE_STUDENT_CHSI_PICTURE_IMPORT);
        smsImportTaskMapper.insert(smsImportTask);
        String taskId = smsImportTask.getId();
        if (isNullOrEmpty(taskId)) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }

        // 批量导入新生信息
        int OFFSET_ROW = 1; // 初始化行数
        int taskStatus = TASK_STATUS_DONE; // 任务状态: 完成
        for (int i = 0; i < chsiPicReqList.size(); i++) {
            // 开启事务
            DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
            // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
            dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 设置嵌套事务
            TransactionStatus status = transactionManager.getTransaction(dt);
            try {
                StuIdChsiPicReq stuIdChsiPicReq = stuIdChsiPicReqList.get(i);
                // 必填字段验证(学生学号/电话/身份证号、表格中图片名)
                if (isNullOrEmpty(stuIdChsiPicReq.getStuNo(), stuIdChsiPicReq.getExelPicName())) {
                    transactionManager.rollback(status);
                    createImportTaskDetail(stuIdChsiPicReq.getStuNo(), stuIdChsiPicReq.getExelPicName(), taskId, REASON_INVALID_PARAM, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }

                // 根据身份证号或手机号或学号匹配学生
                List<SmsStudentInfo> studentInfoList = smsStudentInfoMapper.selectList(new LambdaQueryWrapper<SmsStudentInfo>()
                        .eq(SmsStudentInfo::getStuIdCard, stuIdChsiPicReq.getStuNo()) // 身份证号
                        .or()
                        .eq(SmsStudentInfo::getStuTel, stuIdChsiPicReq.getStuNo()) // 手机号
                        .or()
                        .eq(SmsStudentInfo::getStuNo, stuIdChsiPicReq.getStuNo())); // 学号
                if (studentInfoList.isEmpty()) { // 学籍信息不存在
                    transactionManager.rollback(status);
                    createImportTaskDetail(stuIdChsiPicReq.getStuNo(), stuIdChsiPicReq.getExelPicName(), taskId, REASON_STUDENT_NOT_EXIST, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }
                SmsStudentInfo studentInfo = studentInfoList.get(0);

                // 根据表格中图片名获取图片存储路径
                List<ChsiPicReq> filterChsiPicReqList = chsiPicReqList.stream().filter(chsiPicReq -> Objects.equals(chsiPicReq.getExelPicName(), stuIdChsiPicReq.getExelPicName())).collect(Collectors.toList());
                if (filterChsiPicReqList.isEmpty()) { // 未导入学籍照片
                    transactionManager.rollback(status);
                    createImportTaskDetail(stuIdChsiPicReq.getStuNo(), stuIdChsiPicReq.getExelPicName(), taskId, REASON_STUDENT_CHSI_PICTURE_NOT_EXIST, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }
                String ossPicName = filterChsiPicReqList.get(0).getOssPicName();
                if (isNullOrEmpty(ossPicName)) {
                    transactionManager.rollback(status);
                    createImportTaskDetail(stuIdChsiPicReq.getStuNo(), stuIdChsiPicReq.getExelPicName(), taskId, REASON_INVALID_PARAM, String.valueOf(i + OFFSET_ROW));
                    taskStatus = TASK_STATUS_ERR;
                    continue;
                }

                // 根据添加类型添人
                switch (req.getType()) {
                    case UpdateTypeConstant.UPDATE_TYPE_UPDATE_ADD: // 更新添加
                        List<SmsWnsStudentCardInformation> studentCardInformationList = smsWnsStudentCardInformationMapper.selectList(new LambdaQueryWrapper<SmsWnsStudentCardInformation>()
                                .eq(SmsWnsStudentCardInformation::getStuId, studentInfo.getId()));
                        if (studentCardInformationList.isEmpty()) { // 不存在三证信息
                            SmsWnsStudentCardInformation studentCardInformation = new SmsWnsStudentCardInformation();
                            studentCardInformation.setStuId(studentInfo.getId());
                            // 设置userId
                            List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                                    .eq(SmsUserStudentRelation::getStuId, studentInfo.getId()));
                            studentCardInformation.setUserId(userStudentRelationList.get(0).getUserId());
                            // 设置学籍照片
                            studentCardInformation.setChsiPic(ossPicName);
                            smsWnsStudentCardInformationMapper.insert(studentCardInformation);
                        } else { // 存在三证信息
                            SmsWnsStudentCardInformation studentCardInformation = studentCardInformationList.get(0);
                            studentCardInformation.setChsiPic(ossPicName);
                            smsWnsStudentCardInformationMapper.updateById(studentCardInformation);
                        }

                        break;
                    case UpdateTypeConstant.UPDATE_TYPE_COVER_ADD: // 覆盖添加
                        // 删除原有三证信息
                        smsWnsStudentCardInformationMapper.delete(new LambdaQueryWrapper<SmsWnsStudentCardInformation>()
                                .eq(SmsWnsStudentCardInformation::getStuId, studentInfo.getId()));

                        // 新增三证信息
                        SmsWnsStudentCardInformation studentCardInformation = new SmsWnsStudentCardInformation();
                        studentCardInformation.setStuId(studentInfo.getId());
                        // 设置userId
                        List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                                .eq(SmsUserStudentRelation::getStuId, studentInfo.getId()));
                        studentCardInformation.setUserId(userStudentRelationList.get(0).getUserId());
                        // 设置学籍照片
                        studentCardInformation.setChsiPic(ossPicName);
                        smsWnsStudentCardInformationMapper.insert(studentCardInformation);

                        break;
                }

                // 提交事务
                transactionManager.commit(status);
            } catch (Exception e) {
                e.printStackTrace();
                // 回滚事务
                transactionManager.rollback(status);
            } finally {
                if (status.isNewTransaction() && !status.isCompleted()) {
                    transactionManager.commit(status);
                }
            }
        }

        // 更新任务状态未已结束
        smsImportTask.setStatus(taskStatus);
        smsImportTaskMapper.updateById(smsImportTask);

        return new AsyncResult<>(CommonResult.success());
    }

    @Override
    @Transactional
    public ResponseResult reportSuccess(SmsWnsRegistrationProcessReq req) {
        if (isNullOrEmpty(req.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsWnsRegistrationProcessDetail processDetail = this.getById(req.getId());
        if (processDetail == null) {
            return CommonResult.failed(CommonCodeEnum.WNS_PROCESS_DETAIL_NOT_EXIST);
        }

        processDetail.setStatus(REGISTRATION_PROCESS_DETAIL_STATUS_END);
        this.updateById(processDetail);

        // 流程全部完成激活账号
        // 查询该用户状态不等于已完成流程数
        int count = this.count(new LambdaQueryWrapper<SmsWnsRegistrationProcessDetail>()
                .eq(SmsWnsRegistrationProcessDetail::getUserId, processDetail.getUserId())
                .ne(SmsWnsRegistrationProcessDetail::getStatus, REGISTRATION_PROCESS_DETAIL_STATUS_END));
        if (count == 0) {
            // 校验用户是否存在
            SmsUser user = smsUserMapper.selectById(processDetail.getUserId());
            if (user == null) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.USER_NOT_EXIST));
            }

            user.setIsUse(1); // 激活账号
            smsUserMapper.updateById(user);
        }

        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult updDetailStatus(SmsWnsRegistrationProcessDetailReq req) {
        if (isNullOrEmpty(req.getId(), req.getStatus())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        if (!REGISTRATION_PROCESS_DETAIL_STATUS_LIST.contains(req.getStatus())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsWnsRegistrationProcessDetail processDetail = this.getById(req.getId());
        if (processDetail == null) {
            return CommonResult.failed(CommonCodeEnum.WNS_PROCESS_DETAIL_NOT_EXIST);
        }

        processDetail.setStatus(req.getStatus());
        this.updateById(processDetail);

        // 查询其他步骤状态是否全部完成
        if (req.getStatus() == REGISTRATION_PROCESS_DETAIL_STATUS_END) {
            int count = this.count(new LambdaQueryWrapper<SmsWnsRegistrationProcessDetail>()
                    .eq(SmsWnsRegistrationProcessDetail::getUserId, processDetail.getUserId())
                    .ne(SmsWnsRegistrationProcessDetail::getStatus, REGISTRATION_PROCESS_DETAIL_STATUS_END));
            if (count == 0) {
               // 校验用户是否存在
                SmsUser user = smsUserMapper.selectById(processDetail.getUserId());
                if (user == null) {
                    ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.USER_NOT_EXIST));
                }

                user.setIsUse(1); // 激活账号
                smsUserMapper.updateById(user);
           }
       }

        return CommonResult.success();
    }

    @Override
    public ResponseResult stuInfoList(Integer pageNum, Integer pageSize, Integer orgId, String stuStatus, Integer sort, Integer status, String searchStr) {
        // 构造查询条件
        LambdaQueryWrapper<SmsStudentInfo> queryWrapper = new LambdaQueryWrapper<SmsStudentInfo>()
                .orderByDesc(SmsStudentInfo::getCreateTime);

        // 组织id
        if (orgId != null) {
            List<String> stuIdList = categoryItemUtil.getStuIdByOrgId(orgId);
            if (stuIdList.isEmpty()) {
                queryWrapper.in(SmsStudentInfo::getId, "");
            } else {
                queryWrapper.in(SmsStudentInfo::getId, stuIdList);
            }
        }

        // 学生学籍状态: 0.异常 1.正常 2.休学 3.退学 4.新生入伍 5.在校入伍
        if (!isNullOrEmpty(stuStatus)) {
            queryWrapper.eq(SmsStudentInfo::getStuStatus, stuStatus);
        }

        // 步骤顺序 和 步骤状态(0.未完成 1.进行中 2.已完成 3.失败)
        if (!isNullOrEmpty(sort, status)) {
            List<SmsWnsRegistrationProcessDetail> processDetailList = smsWnsRegistrationProcessDetailMapper.selectList(new LambdaQueryWrapper<SmsWnsRegistrationProcessDetail>()
                    .eq(SmsWnsRegistrationProcessDetail::getSort, sort)
                    .eq(SmsWnsRegistrationProcessDetail::getStatus, status));
            List<String> userIdList = processDetailList.stream().map(SmsWnsRegistrationProcessDetail::getUserId).collect(Collectors.toList());
            List<String> stuIdList = categoryItemUtil.getStuIdListByUserIdList(userIdList);
            if (stuIdList.isEmpty()) {
                queryWrapper.in(SmsStudentInfo::getId, "");
            } else {
                queryWrapper.in(SmsStudentInfo::getId, stuIdList);
            }
        }

        // 查询字符串
        if (!isNullOrEmpty(searchStr)) {
            queryWrapper.and(i -> i.like(SmsStudentInfo::getStuNo, searchStr).or()
                    .like(SmsStudentInfo::getStuName, searchStr).or()
                    .like(SmsStudentInfo::getStuTel, searchStr).or()
                    .like(SmsStudentInfo::getStuIdCard, searchStr).or()
                    .like(SmsStudentInfo::getStuSex, searchStr).or()
                    .like(SmsStudentInfo::getStuCollege, searchStr).or()
                    .like(SmsStudentInfo::getStuMajor, searchStr).or()
                    .like(SmsStudentInfo::getStuGrade, searchStr).or()
                    .like(SmsStudentInfo::getStuClass, searchStr).or()
                    .like(SmsStudentInfo::getStuNation, searchStr).or()
                    .like(SmsStudentInfo::getStuNativePlace, searchStr));
        }

        Page<SmsStudentInfo> page = new Page<>(pageNum, pageSize);
        smsStudentInfoMapper.selectPage(page, queryWrapper);
        List<StuInfoResp> collect = page.getRecords().stream().map(studentInfo -> {
            StuInfoResp stuInfoResp = new StuInfoResp();
            // 设置学生基本信息
            stuInfoResp.setStudentInfo(studentInfo);

            // 设置报到流程状态集合
            List<SmsWnsRegistrationProcessDetail> processDetailList = categoryItemUtil.getProcessListByStuId(studentInfo.getId());
            stuInfoResp.setProcessDetailList(processDetailList);

            // 设置班主任信息集合
            List<SmsUser> assistantList = assistantUtil.getAssistantsByStuId(studentInfo.getId());
            stuInfoResp.setAssistantList(assistantList);

            // 财务处报道
            if (sort == REGISTRATION_PROCESS_DETAIL_SORT_TWO) {
                // 设置总收费状态
                SmsWnsChargePlanStudentStatusResp statusResp = categoryItemUtil.getTotalStatusByStuId(studentInfo.getId());
                stuInfoResp.setStatusResp(statusResp);
            } else if (sort == REGISTRATION_PROCESS_DETAIL_SORT_FIVE) { // 后勤处报道
                // 设置宿舍及床号信息
                List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                        .in(SmsUserStudentRelation::getStuId, studentInfo.getId()));
                if (!userStudentRelationList.isEmpty()) {
                    List<SmsDormitoryBed> dormitoryBedList = smsDormitoryBedMapper.selectList(new LambdaQueryWrapper<SmsDormitoryBed>()
                            .eq(SmsDormitoryBed::getUserId, userStudentRelationList.get(0).getUserId()));
                    if (!dormitoryBedList.isEmpty()) {
                        SmsDormitory dormitory = smsDormitoryMapper.selectById(dormitoryBedList.get(0).getDormitoryId());
                        stuInfoResp.setDormitoryBed(dormitoryBedList.get(0));
                        stuInfoResp.setDormitory(dormitory);
                    }
                }
            }

            return stuInfoResp;
        }).collect(Collectors.toList());

        return CommonResult.success(collect, (int) page.getTotal());
    }

    @Override
    public ResponseResult stuInfoDetail(String stuId, Integer sort) {
        SmsStudentInfo studentInfo = smsStudentInfoMapper.selectById(stuId);
        if (studentInfo == null) {
            return CommonResult.failed(CommonCodeEnum.STUDENT_NOT_EXIST);
        }

        StuInfoResp stuInfoResp = new StuInfoResp();
        // 设置学生基本信息
        stuInfoResp.setStudentInfo(studentInfo);

        // 设置报到流程状态集合
        List<SmsWnsRegistrationProcessDetail> processDetailList = categoryItemUtil.getProcessListByStuId(stuId);
        stuInfoResp.setProcessDetailList(processDetailList);

        // 设置班主任信息集合
        List<SmsUser> assistantList = assistantUtil.getAssistantsByStuId(stuId);
        stuInfoResp.setAssistantList(assistantList);

        // 招生就业处报道
        if (sort == REGISTRATION_PROCESS_DETAIL_SORT_ONE) {
            SmsWnsChargePlanStudentStatusResp statusResp = categoryItemUtil.getTotalStatusByStuId(stuId);
            stuInfoResp.setStatusResp(statusResp);

            // 设置三证信息
            List<SmsWnsStudentCardInformation> studentCardInformationList = smsWnsStudentCardInformationMapper.selectList(new LambdaQueryWrapper<SmsWnsStudentCardInformation>()
                    .eq(SmsWnsStudentCardInformation::getStuId, stuId));
            if (!studentCardInformationList.isEmpty()) {
                SmsWnsStudentCardInformationResp cardInformationResp = new SmsWnsStudentCardInformationResp();
                BeanUtils.copyProperties(studentCardInformationList.get(0), cardInformationResp);
                stuInfoResp.setCardInformationResp(cardInformationResp);
            }
        } else if (sort == REGISTRATION_PROCESS_DETAIL_SORT_TWO) { // 财务处报道
            // 设置总收费状态
            SmsWnsChargePlanStudentStatusResp statusResp = categoryItemUtil.getTotalStatusByStuId(stuId);
            stuInfoResp.setStatusResp(statusResp);

            // 获取该生所有计划以及所有缴费项缴费情况
            List<PlanAndStatusListResp> planAndStatusList = categoryItemUtil.getPlanAndStatusList(stuId);
            stuInfoResp.setPlanAndStatusList(planAndStatusList);
        }

        // 设置宿舍及床号信息
        List<SmsUserStudentRelation> userStudentRelationList = smsUserStudentRelationMapper.selectList(new LambdaQueryWrapper<SmsUserStudentRelation>()
                .in(SmsUserStudentRelation::getStuId, stuId));
        if (!userStudentRelationList.isEmpty()) {
            List<SmsDormitoryBed> dormitoryBedList = smsDormitoryBedMapper.selectList(new LambdaQueryWrapper<SmsDormitoryBed>()
                    .eq(SmsDormitoryBed::getUserId, userStudentRelationList.get(0).getUserId()));
            if (!dormitoryBedList.isEmpty()) {
                SmsDormitory dormitory = smsDormitoryMapper.selectById(dormitoryBedList.get(0).getDormitoryId());
                stuInfoResp.setDormitoryBed(dormitoryBedList.get(0));
                stuInfoResp.setDormitory(dormitory);
            }
        }

        return CommonResult.success(stuInfoResp);
    }

    @Override
    public ResponseResult stuOrgUpdateHistoryList(Integer pageNum, Integer pageSize, String searchStr) {
        LambdaQueryWrapper<SmsStuOrgUpdateHistory> queryWrapper = new LambdaQueryWrapper<SmsStuOrgUpdateHistory>()
                .orderByDesc(SmsStuOrgUpdateHistory::getCreateTime);

        if (!isNullOrEmpty(searchStr)) {
            List<String> stuIdList = orgUserStuUtil.getStuIdListBySearchStr(searchStr);
            queryWrapper.in(SmsStuOrgUpdateHistory::getStuId, stuIdList.isEmpty() ? Collections.singletonList("") : stuIdList);
        }

        Page<SmsStuOrgUpdateHistory> page = new Page<>(pageNum, pageSize);
        smsStuOrgUpdateHistoryService.page(page, queryWrapper);
        List<SmsStuOrgUpdateHistoryResp> collect = page.getRecords().stream().map(history -> {
            SmsStuOrgUpdateHistoryResp historyResp = new SmsStuOrgUpdateHistoryResp();
            BeanUtils.copyProperties(history, historyResp);

            SmsStudentInfo studentInfo = smsStudentInfoMapper.selectById(history.getStuId());
            if (studentInfo != null) {
                historyResp.setStudentInfo(studentInfo);
            }

            return historyResp;
        }).collect(Collectors.toList());

        return CommonResult.success(collect, (int) page.getTotal());
    }

    @Override
    public ResponseResult stuOrgUpdateHistoryListByUserId(Integer pageNum, Integer pageSize, String userId) {
        Page<SmsStuOrgUpdateHistory> page = new Page<>(pageNum, pageSize);
        smsStuOrgUpdateHistoryService.page(page, new LambdaQueryWrapper<SmsStuOrgUpdateHistory>()
                .eq(SmsStuOrgUpdateHistory::getUserId, userId));

        List<SmsStuOrgUpdateHistoryResp> collect = page.getRecords().stream().map(history -> {
            SmsStuOrgUpdateHistoryResp historyResp = new SmsStuOrgUpdateHistoryResp();
            BeanUtils.copyProperties(history, historyResp);

            return historyResp;
        }).collect(Collectors.toList());

        return CommonResult.success(collect, (int) page.getTotal());
    }


}
